$TITLE ('RTX-51 DISPATCHER')
$SYMBOLS
$NOXREF
$NOCOND
$NOMOD51
$NORB
$PAGELENGTH(80) PAGEWIDTH(110)
;************************************************************************
;*                                                                      *
;*    R T X - 5 1  :   DISPATCHER                                       *
;*                                                                      *
;*----------------------------------------------------------------------*
;*                                                                      *
;*    Filename     :   RTXDISP.A51                                      *
;*    Language     :   Keil A-51                                        *
;*    Dev. system  :   Keil uVision2                                    *
;*    Targetsystem :   Any system based upon 8051 up                    *
;*                                                                      *
;*    Purpose      :   Central dispatcher of RTX-51.                    *
;*                     Will be executed by RTX-51 after an event        *
;*                     which affects the ready_list and could           *
;*                     cause a task_switching (preemption).             *
;*                                                                      *
;*----------------------------------------------------------------------*
;* Rev. |  Released   | Programmer    | Comments                        *
;*----------------------------------------------------------------------*
;* 0.1  |  10.1.1991  | E. Glatz      | Changes for V3.20               *
;* 0.2  |  27.3.1991  | Th. Fischler  | C-51 parameter passing for V4.0 *
;*      |  10.4.1991  |               | P2-addressing eliminated        *
;*      |             |               | New context handling            *
;*      |  28.8.1991  | Th. Fischler  | Round-Robin Scheduling only     *
;*      |             |               | with priority 0 Tasks           *
;*      |  18.9.1991  |               | Supervisor-Mode flag handling   *
;*      | 19.11.1991  | Th. Fischler  | Correct Handling of PSW in      *
;*      |             |               | Full-Context                    *
;*      | 14.4.1992   | Th. Fischler  | Changes for code-bankswitching  *
;*      |             |               | support                         *
;*      | 27.4.1992   | Th. Fischler  | Error with Round-Robin          *
;*      |             |               | dispatching corrected           *
;*      |  4.06.1992  |               | RTXINS.INC converted to proc.   *
;* 0.3  | 27.10.1992  | Th. Fischler  | Reading P2 problems solved      *
;* 5.00 | 13.10.1994  | E. Glatz      | Comments added                  *
;* 5.10 |   8.05.96   |               | Add ext. ref. ?RTX_IDLE_FUNC    *
;* 7.00 | 13.11.2001  | T. Mueller    | Page addressing configurable    *
;************************************************************************
;*    Copyright 1991 .. 2001 METTLER  &  FUCHS  AG,  CH-8953 Dietikon   *
;************************************************************************

$INCLUDE (RTXDEBUG.INC)
$INCLUDE (RTXIMASK.INC)
$INCLUDE (RTXGETPR.INC)
$INCLUDE (RTXREMOV.INC)
$INCLUDE (RTXREINS.INC)


;*----------------------------------------------------------------------*
;*      I M P O R T S
;*----------------------------------------------------------------------*

$INCLUDE (RTXCONST.INC)
$INCLUDE (RTXEXTRN.INC)

;        FROM RTXSEND
EXTRN    CODE    (?RTX_NFL_NDEVENT, ?RTX_NFL_DEVENT)

;        FROM RTXCONF
EXTRN    DATA  (?RTX_SAVE_INT_BANK, ?B_CURRENTBANK, ?RTX_PAGE_OUT_REG)
EXTRN    CODE  (?RTX_SWITCHBANK)

;        FROM RTXINS
EXTRN    CODE  (?RTX_INSERT_RDY_PRIO)

;        FROM RTXCONF
EXTRN    CODE  (?RTX_IDLE_FUNC)


;*----------------------------------------------------------------------*
;*      E X P O R T S
;*----------------------------------------------------------------------*

PUBLIC  ?RTX_REDISPATCH


;*----------------------------------------------------------------------*
;*      D U M M Y - S T A C K   D E C L A R A T I O N
;*----------------------------------------------------------------------*

?STACK         SEGMENT  IDATA
               RSEG     ?STACK
               DS 1


;*----------------------------------------------------------------------*
;*      P R O C E D U R E S
;*----------------------------------------------------------------------*

;*----------------------------------------------------------------------*
;*      ? R T X _ R E D I S P A T C H
;*----------------------------------------------------------------------*
;*      Dispatcher. 
;*----------------------------------------------------------------------*
;*      Input:   - all task interrupts must be disabled !
;*      Output:  - 
;*----------------------------------------------------------------------*

?RTX?REDISPATCH?RTXDISP  SEGMENT CODE
                         RSEG    ?RTX?REDISPATCH?RTXDISP

?RTX_REDISPATCH:
               ; Check if already deallocated
               JB    ?RTX_PROCESSOR_ALLOCATED, ALLOC
;
;       Processor is DEALLOCATED
;
               ; Clear redispatch request
               CLR   ?RTX_REQ_REDISPATCH
               ; Check if a fast task (=driver task) is ready to execute
               MOV   A, ?RTX_RDY_COUNT3
               JNZ   READY_DRIVER               ; short-cut if yes
               ; Use standard task (=non driver task) stack if processor 
               ; is deallocated
               MOV   SP, #?STACK-1
               ; Use reg.bank 0, SV_mode on
               MOV   PSW, #00H
               SETB  ?RTX_SUPERVISOR_MODE
               RTX_ALLOW_DRV_INT
               JMP   ASSIGN

READY_DRIVER:  JMP   ASSIGN_D
;
;       Resume when running task is a FAST TASK (=driver task)
;
RESUME_D:      SETB  ?RTX_FULL_CONTEXT          ; In case an asynchronous
                                                ; reset occurred
               CLR   ?RTX_SUPERVISOR_MODE       ; Supervisor_mode := off
               DBG_SYS_EXIT                     ; Do not allow interrupts !
               RET
;
;       Check for PREEMPTION
;
ALLOC:         ; Check if fast task (=driver task)
               JB    ?RTX_RUNNING_TID.4, RESUME_D
               ; Clear redispatch request
               CLR   ?RTX_REQ_REDISPATCH

;
;              This window (for fast task interrupts) is allowed because
;              fast tasks may not enter this section.
;
               ; Supervisor_mode := on
               SETB    ?RTX_SUPERVISOR_MODE
               RTX_ALLOW_DRV_INT
               ; Save ACC, PSW and B
               MOV     ?RTX_DISP_TMP1, A
               MOV     ?RTX_DISP_TMP5, PSW
               MOV     ?RTX_DISP_TMP3, B
               ; Get highest ready priority to compare it with
               ; running prio.
               RTX_EXCLUDE_INT
               CLR   ?RTX_ROUND_ROBIN_OK
               GET_RDY_PRIO
               ; Check if no other ready-task in system
               CJNE  A, #0FFH, RDY_TASK
               JMP   NOPREEMPT
               ; Check if ready prio. is higher than running prio.
RDY_TASK:      RR    A
               RR    A
               MOV   B, ?RTX_RUNNING_TID
               ANL   B, #0C0H                   ; extract the prio
               XCH   A, B
               CLR   C
               SUBB  A, B
               JNC   CHECK_2
               JMP   PREEMPT

CHECK_2:       JNB   ?RTX_ROUND_ROBIN_REQ, NOPREEMPT
               MOV   A, ?RTX_RUNNING_TID
               ANL   A, #0C0H
               ORL   A, B
               JZ    PREEMPT                    ; Schedule only when both
                                                ; tasks have prio 0

;       RESUME (Do not switch to new task)
;       
NOPREEMPT:     ; Restore ACC, PSW and B
               MOV   A, ?RTX_DISP_TMP1
               MOV   PSW, ?RTX_DISP_TMP5
               MOV   B, ?RTX_DISP_TMP3
               ; Check if a new redispatch request was generated
               RTX_EXCLUDE_INT
               JB    ?RTX_REQ_REDISPATCH, RED1
               ; Supervisor_mode := off
               CLR     ?RTX_SUPERVISOR_MODE
               DBG_SYS_EXIT
               RTX_ALLOW_INT
               RET

RED1:           
               RTX_EXCLUDE_INT
               JMP   ?RTX_REDISPATCH
REDUC:         JMP   REDU
;
;       PREEMPTION (Switch to highest prio. ready task)
;
;       (This point will be reached only by standard tasks as fast tasks
;        are never subject to preemption during normal redispatching)
;
PREEMPT:       JNB   ?RTX_ROUND_ROBIN_REQ, GO_ON
               MOV   A, ?RTX_RUNNING_TID
               ANL   A, #0C0H
               JNZ   GO_ON                      ; only round-robin if prio=0
               SETB  ?RTX_ROUND_ROBIN_OK
GO_ON:         CLR   ?RTX_ROUND_ROBIN_REQ
               RTX_ALLOW_DRV_INT
               MOV   A, ?RTX_DISP_TMP1          ; Restore ACC
               MOV   B, ?RTX_DISP_TMP3          ; Restore B

;
;       RESIGN
;
;       (store context of allocated task, insert its task_id in
;        the ready-list)
;
RESIGN:        ; Check if full or reduced context has to be saved
               JNB   ?RTX_FULL_CONTEXT, REDUC
;
;       Save full context (of standard task)
;              ; Save DPTR, ACC and B temporary
               MOV   ?RTX_DISP_TMP1, DPH
               MOV   ?RTX_DISP_TMP2, DPL
               MOV   ?RTX_DISP_TMP3, A
               MOV   ?RTX_DISP_TMP4, B

               ; Set up DPTR as pointer to tasks register save area
               MOV   A, ?RTX_RUNNING_TID
               ANL   A, #0FH
               MOV   B, A
               MOV   A, #LOW(?RTX_KNTXT_PTR_TABLE)
               ADD   A, B
               ADD   A, B
               MOV   DPL, A
               MOV   DPH, #HIGH(?RTX_KNTXT_PTR_TABLE)
               MOVX  A, @DPTR
               MOV   B, A
               INC   DPL
               MOVX  A, @DPTR
               MOV   DPL, A
               MOV   DPH, B

               ; store ACC in context area
               MOV   A, ?RTX_DISP_TMP3
               MOVX  @DPTR, A
               INC   DPL

               ; Store R7..R0 in context area
               MOV   A, R7
               MOVX  @DPTR, A
               INC   DPL
               ; Store R6
               MOV   A, R6
               MOVX  @DPTR, A
               INC   DPL
               ; Store R5
               MOV   A, R5
               MOVX  @DPTR, A
               INC   DPL
               ; Stor  R4
               MOV   A, R4
               MOVX  @DPTR, A
               INC   DPL
               ; Store R3
               MOV   A, R3
               MOVX  @DPTR, A
               INC   DPL
               ; Store R2
               MOV   A, R2
               MOVX  @DPTR, A
               INC   DPL
               ; Store R1
               MOV   A, R1
               MOVX  @DPTR, A
               INC   DPL
               ; Store R0
               MOV   A, R0
               MOVX  @DPTR, A
               INC   DPL
               ; Store B
               MOV   A, ?RTX_DISP_TMP4
               MOVX  @DPTR, A
               INC   DPL
               ; Store DPH
               MOV   A, ?RTX_DISP_TMP1
               MOVX  @DPTR, A
               INC   DPL
               ; Store DPL
               MOV   A, ?RTX_DISP_TMP2
               MOVX  @DPTR, A
               INC   DPL
               ; Store PSW
               MOV   A, ?RTX_DISP_TMP5
               MOVX  @DPTR, A
               INC   DPL
               ; Store SP
               MOV   A, SP
               MOVX  @DPTR, A
               INC   DPL
               ; Context_type := 'full'
               MOV   A, #FULL
               MOVX  @DPTR, A
               INC   DPL
               ; Store reentrant Stackpointer
               MOV   A, ?RTX_P2_MIR
               MOVX  @DPTR, A
               INC   DPL
               MOV   A, ?RTX_PBP
               MOVX  @DPTR, A
               INC   DPL
               JNB   ?RTX_BANKSW, NO_BA
               ; Store banknumber
               MOV   A, ?B_CURRENTBANK
               MOVX  @DPTR, A

               ; Calculate stack size
NO_BA:         MOV   A, SP
               CLR   C
               SUBB  A, #?STACK-1
               MOV   B,A                        ; B := stack byte count
               ; Set up ptr to stack save area
               MOV   A, DPL
               ADD   A, B
               MOV   DPL, A
SAVE_STACK1:   POP   ACC
               MOVX  @DPTR, A
               DEC   DPL
               DJNZ  B, SAVE_STACK1
               JMP   END_RESIGN
;
;       Save reduced context (of standard task)
;
REDU:
               ; Set up DPTR as pointer to tasks register save area
               MOV   A, ?RTX_RUNNING_TID
               ANL   A, #0FH
               MOV   B, A
               MOV   A, #LOW(?RTX_KNTXT_PTR_TABLE)
               ADD   A, B
               ADD   A, B
               MOV   DPL, A
               MOV   DPH, #HIGH(?RTX_KNTXT_PTR_TABLE)
               MOVX  A, @DPTR
               MOV   B, A
               INC   DPL
               MOVX  A, @DPTR
               MOV   DPL, A
               MOV   DPH, B

               MOV   A, R7                      ; Store R7
               INC   DPL
               MOVX  @DPTR, A
                                                ; Store SP
               MOV   A, DPL
               ADD   A, #0CH
               MOV   DPL, A
               MOV   A, SP
               MOVX  @DPTR, A
               INC   DPL
               ; Context_type := 'reduced'
               MOV   A, #REDUCED
               MOVX  @DPTR, A
               INC   DPL
               ; Store reentrant Stackpointer
               MOV   A, ?RTX_P2_MIR
               MOVX  @DPTR, A
               INC   DPL
               MOV   A, ?RTX_PBP
               MOVX  @DPTR, A
               INC   DPL
               JNB   ?RTX_BANKSW, NO_BA1
               ; Store banknumber
               MOV   A, ?B_CURRENTBANK
               MOVX  @DPTR, A

               ; Calculate stack size
NO_BA1:        MOV   A, SP
               CLR   C
               SUBB  A, #?STACK-1
               MOV   B,A                        ; B := stack byte count
               ; Set up ptr to stack save area
               MOV   A, DPL
               ADD   A, B
               MOV   DPL, A
SAVE_STACK2:   POP   ACC
               MOVX  @DPTR, A
               DEC   DPL
               DJNZ  B, SAVE_STACK2

;
;
END_RESIGN:     
               RTX_EXCLUDE_INT
               JB ?RTX_ROUND_ROBIN_OK, W_RR     ; check if round_robin
               REINSERT_RDY_PRIO  ?RTX_RUNNING_TID
               JMP   CONT_ASS
W_RR:          ; with round-robin
               POP   ?RTX_TMP1                  ; Make free 2 bytes of stack
               POP   ?RTX_TMP2                  ; for subroutine call
               MOV   A, ?RTX_RUNNING_TID
               CALL  ?RTX_INSERT_RDY_PRIO
               PUSH  ?RTX_TMP2                  ; Restore return address
               PUSH  ?RTX_TMP1                  ; to stack
CONT_ASS:      RTX_ALLOW_DRV_INT
               CLR   ?RTX_PROCESSOR_ALLOCATED   ; := DEALLOCATED

;
;       ASSIGN
;
;       (Get task_id of next ready-task and restore its context)
;
ASSIGN:         
               RTX_EXCLUDE_INT

ASSIGN_D:      REMOVE_RDY_PRIO                  ; Get next ready task

               SETB  ?RTX_PROCESSOR_ALLOCATED   ; := ALLOCATED

               MOV     ?RTX_RUNNING_TID, A

               $IF (DBG = 02H)
                  MOV     DPTR, #?RTX_DEBUG_TID
                  MOVX    @DPTR, A
               $ENDIF

               JNB     ?RTX_RUNNING_TID.4, NOT_DRIVER
;                                      
;       ASSIGN (fast task)
;
               JB    ?RTX_RUNNING_TID.1, NEWDRIVER3
               JB    ?RTX_RUNNING_TID.0, NEWDRIVER2

;
;     RESTORE FAST TASK CONTEXT 
;     (SP, reentrant SP, Code-Bank, select reg.bank 1)
;
NEWDRIVER1:    MOV   PSW, #08H                  ; RBS=01, SV_mode=on
               SETB  ?RTX_SUPERVISOR_MODE
               MOV   R0, #?RTX_FTASKDATA?1
               JMP   REST_D

NEWDRIVER2:    MOV   PSW, #10H                  ; RBS=10, SV_mode=on
               SETB  ?RTX_SUPERVISOR_MODE
               MOV   R0, #?RTX_FTASKDATA?2
               JMP   REST_D

NEWDRIVER3:    MOV   PSW, #18H                  ; RBS=11, SV_mode=on
               SETB  ?RTX_SUPERVISOR_MODE
               MOV   R0, #?RTX_FTASKDATA?3

REST_D:        MOV   SP, @R0
               JNB   ?RTX_REENTRANTFLAG, NOT_R
               GLOBAL_INT_DISABLE
               INC   R0
               MOV   ?RTX_PAGE_OUT_REG, @R0
               MOV   ?RTX_P2_MIR, @R0
               INC   R0
               MOV   ?RTX_PBP, @R0
               GLOBAL_INT_ENABLE
               JMP   CHK_BANK
NOT_R:         INC   R0
               INC   R0
CHK_BANK:      JNB   ?RTX_BANKSW, CONT
               INC   R0
               MOV   A, @R0
               GLOBAL_INT_DISABLE
               MOV   ?RTX_TMP1, R7
               CALL  ?RTX_SWITCHBANK
               MOV   R7, ?RTX_TMP1
               GLOBAL_INT_ENABLE

               ; Check if return from nf-wait
CONT:          CJNE  R7, #NFL_EVENT, END_ASSIGN_D
               JMP     ?RTX_NFL_DEVENT

END_ASSIGN_D:   
               CLR   ?RTX_SUPERVISOR_MODE       ; Supervisor_mode := off
               DBG_SYS_EXIT                     ; Do not alllow interrupts !
               RET

;
;       ASSIGN (standard task)
;
NOT_DRIVER:     
               MOV   PSW, #00H                  ; RBS = 0, SV_mode = on
               SETB  ?RTX_SUPERVISOR_MODE
               RTX_ALLOW_DRV_INT

;
;       Restore standard task context
;
;       (Full or Reduced context depending on stored context_type)
;
               ; Set up ptr to saved context type
               MOV   A, ?RTX_RUNNING_TID
               ANL   A, #0FH
               MOV   B, A
               MOV   A, #LOW(?RTX_KNTXT_PTR_TABLE)
               ADD   A, B
               ADD   A, B
               MOV   DPL, A
               MOV   DPH, #HIGH(?RTX_KNTXT_PTR_TABLE)
               MOVX  A, @DPTR
               MOV   B, A
               INC   DPL
               MOVX  A, @DPTR
               MOV   DPH, B
               MOV   ?RTX_DISP_TMP1, A          ; save context start-adr.

               ;  Check if bankswitching required
               JNB   ?RTX_BANKSW, NOT_BANK
               MOV   SP, #?STACK-1              ; Rewind stackpointer
               ADD   A, #11H                    ; banknumber offset
               MOV   DPL, A
               MOVX  A, @DPTR
               GLOBAL_INT_DISABLE
               MOV   ?RTX_TMP1, DPH             ; Save DPH
               CALL  ?RTX_SWITCHBANK
               MOV   DPH, ?RTX_TMP1
               GLOBAL_INT_ENABLE

NOT_BANK:      MOV   A, ?RTX_DISP_TMP1
               ADD   A, #0EH                    ; context-type offset
               MOV   DPL, A
         
               ; Check context type
               MOVX  A, @DPTR
               CJNE  A, #FULL, REDUCED_CONTEXT
               JMP   F_CONTEXT
;
;       Restore reduced context (of standard task)
;
REDUCED_CONTEXT:
               ; Restore SP
CONT_REDU:     DEC   DPL
               MOVX  A, @DPTR
               ; Calculate stack size
               CLR   C
               SUBB  A, #?STACK-1
               MOV   B, A                       ; B:= stack byte count

               MOV   DPL, ?RTX_DISP_TMP1        ; DPTR to saved context

               INC   DPL                        ; Restore R7
               MOVX  A, @DPTR
               MOV   R7, A
               ; Check if restore of R6/R5/R4
               CJNE  R7, #NFL_EVENT, NO_RESTREG
                                                ; Restore R6
               INC   DPL
               MOVX  A, @DPTR
               MOV   R6, A
                                                ; Restore R5
               INC   DPL
               MOVX  A, @DPTR
               MOV   R5, A
                                                ; Restore R4
               INC   DPL
               MOVX  A, @DPTR
               MOV   R4, A
NO_RESTREG:
               JNB   ?RTX_REENTRANTFLAG, NOT_R4
               ;  Restore reentrant Stackpointer
               MOV   A, ?RTX_DISP_TMP1
               ADD   A, #0FH
               MOV   DPL, A
               GLOBAL_INT_DISABLE
               MOVX  A, @DPTR
               MOV   ?RTX_PAGE_OUT_REG, A
               MOV   ?RTX_P2_MIR, A
               INC   DPL
               MOVX  A, @DPTR
               MOV   ?RTX_PBP, A
               GLOBAL_INT_ENABLE

NOT_R4:        MOV   A, ?RTX_DISP_TMP1
               ADD   A, #?RTX_EXTREGSIZE
               MOV   DPL, A

               ; Restore Stack
               MOV   SP, #?STACK-1              ; Rewind stackpointer

RESTORE_STACK1:
               ; Move stack data to nd stack
               MOVX  A, @DPTR
               INC   DPL
               PUSH  ACC
               DJNZ  B, RESTORE_STACK1
               ; Check if ret.status=NFL_EVENT
               CJNE  R7, #NFL_EVENT, END_ASSIGN_LBL
               JMP   NFL_END_ASSIGN
END_ASSIGN_LBL:
               JMP   END_ASSIGN
;
;       Restore full context (of standard task)
;
F_CONTEXT:     MOV   DPL, ?RTX_DISP_TMP1

               MOVX  A, @DPTR                   ; Restore ACC (to temporary
               INC   DPL                        ; save var. ?RTX_DISP_TMP2)
               MOV   ?RTX_DISP_TMP2, A
               ; Restore R7..R0
               MOVX  A, @DPTR
               INC   DPL
               MOV   R7, A
               MOVX  A, @DPTR
               INC   DPL
               MOV   R6, A
               MOVX  A, @DPTR
               INC   DPL
               MOV   R5, A
               MOVX  A, @DPTR
               INC   DPL
               MOV   R4, A
               MOVX  A, @DPTR
               INC   DPL
               MOV   R3, A
               MOVX  A, @DPTR
               INC   DPL
               MOV   R2, A
               MOVX  A, @DPTR
               INC   DPL
               MOV   R1, A
               MOVX  A, @DPTR
               INC   DPL
               MOV   R0, A

               INC   DPL                        ; B & DPTR will be used,
               INC   DPL                        ; restore later.
               INC   DPL
               INC   DPL                        ; PSW should not be restored
                                                ; here ! --> restore PSW later
               MOVX  A, @DPTR
               CLR   C                          ; Calculate stack size
               SUBB  A, #?STACK-1
               MOV   B, A                       ; B:= stack byte count
               ;  Restore reentrant Stackpointer
               JNB   ?RTX_REENTRANTFLAG, NOT_R5

               INC   DPL
               INC   DPL
               GLOBAL_INT_DISABLE
               MOVX  A, @DPTR
               MOV   ?RTX_PAGE_OUT_REG, A
               MOV   ?RTX_P2_MIR, A
               INC   DPL
               MOVX  A, @DPTR
               MOV   ?RTX_PBP, A
               GLOBAL_INT_ENABLE

NOT_R5:        MOV   A, ?RTX_DISP_TMP1          ; DPTR points to stack-context
               ADD   A, #?RTX_EXTREGSIZE
               MOV   DPL, A

               ; Restore stack
               MOV   SP, #?STACK-1              ; Rewind stackpointer

RESTORE_STACK2:
               ; Move stack data to nd stack
               MOVX  A, @DPTR
               INC   DPL
               PUSH  ACC
               DJNZ  B, RESTORE_STACK2

               ; Restore B now
               MOV   A, ?RTX_DISP_TMP1
               ADD   A, #09H
               MOV   DPL, A
               MOVX  A, @DPTR
               MOV   B, A
               ; Restore DPH to ?RTX_DISP_TMP1
               INC   DPL
               MOVX  A, @DPTR
               MOV   ?RTX_DISP_TMP1, A
               ; Restore DPL to ?RTX_DISP_TMP3
               INC   DPL
               MOVX  A, @DPTR
               MOV   ?RTX_DISP_TMP3, A
               ; Restore PSW
               INC   DPL
               MOVX  A, @DPTR
               MOV   PSW, A
               ; Restore DPH, DPL, PSW and ACC from temp.
               MOV   DPH, ?RTX_DISP_TMP1
               MOV   DPL, ?RTX_DISP_TMP3
               MOV   A, ?RTX_DISP_TMP2


END_ASSIGN:    RTX_EXCLUDE_INT
               JB    ?RTX_REQ_REDISPATCH, RED2  ; Redispatch again if re-
                                                ; quest set
               CLR   ?RTX_SUPERVISOR_MODE       ; Supervisor_mode := off
               DBG_SYS_EXIT
               RTX_ALLOW_INT
               RET

NFL_END_ASSIGN:                                 ; Supervisor_mode is already ON
                                                ; Allow fast task int. only, 
               RTX_ALLOW_DRV_INT                ; because we are still in SYSTEM
               JMP   ?RTX_NFL_NDEVENT

RED2:          JMP   ?RTX_REDISPATCH

;
;   END OF MODULE
;
        END
